#include <stdio.h> // 不仅有对终端的输入输出操作，文件操作也在这里面
#include <stdlib.h>

// 要考虑大文件拷贝
void CopyFile(const char *destFile, const char *srcFile, int CountSize)
{
    FILE *fr = fopen(srcFile, "r");
    if(fr == NULL)
    {
        printf("文件打开失败!\n");
        return;
    }

    FILE *fw = fopen(srcFile, "w");
    if(fr == NULL)
    {
        printf("文件打开失败!\n");
        return;
    }

    char c = 0;
    while( (c = fgetc(fr)) != EOF)
    {
        fputc(c, fw);
    }

    fseek(fr, 0, SEEK_END); // 把光标移到末尾
    long fileSize = ftell(fr); // 返回当前光标到初始位置的偏移量
    fseek(fr, 0, SEEK_SET); // 把光标移到开头

    // 分次读：分片
    int readSize = 0;
    char *s = (char *)malloc(CountSize);
    while(readSize < fileSize)
    {
        fread(s, CountSize, 1, fr);
        fwrite(s, CountSize, 1, fw);

        readSize += CountSize;
    }
    free(s);
    fclose(fr);
    fclose(fw);
}


int main()
{
#if 0
    // 打开文件
    // 绝对路径：从系统根目录开始排列的路径
    // 相对路径：相对于执行程序的路径
    // w：只写——文件不存在就创建新文件，存在就清空文件
    // r：只读——文件不存在就报错，存在就打开
    // a：append(追加)——文件不存在就创建，存在就追加写
    // w+  r+  a+ ：读写，其他权限和 w/r/a 一样
    // FILE * ：文件指针
    FILE *f = fopen("./test.txt", "r");
    if (f == NULL)
    {
        printf("文件打开失败!\n");
        return -1;
    }
    printf("文件打开成功!\n");

    // EOF：文件结尾（End of File）
    // 当读取一个文件的指针达到文件末尾时，通常会返回一个 EOF 标志，指示文件已经没有更多数据可以读取
    char c = 0;
    // 循环读
    // fgetc()：从文件中读取一个字符（从光标开始）
    // 光标默认在开头（a：光标在尾部，因为它是追加）
    while ((c = fgetc(f)) != EOF)
    {
        printf("%c", c);
    }
    printf("\n");

    // 关闭文件（释放资源）
    fclose(f);
#endif

#if 0
    FILE *f = fopen("./test1.txt", "w");
    if (f == NULL)
    {
        printf("文件打开失败!\n");
        return -1;
    }

    // fputc()往里面写东西
    fputc('h', f);
    fputc('e', f);
    fputc('l', f);
    fputc('\n', f);
    fputc('h', f);
    fputc('e', f);
    fputc('l', f);

    CopyFile("./test1.txt", "./test.txt");

    // 关闭文件（释放资源）
    fclose(f);
#endif

#if 0
    FILE *f = fopen("./test.txt", "r");
    if(f == NULL)
    {
        printf("文件打开失败!\n");
        return -1;
    }

    char s[256] = {0};
    // 读到换行符就结束了
    // 如果一行超过256个，就只读255个，结尾留\0
    fgets(s, 256, f);
    printf("s\n", s);
    fclose(f);
#endif

#if 0
    FILE *f = fopen("./test.txt", "w");
    if(f == NULL)
    {
        printf("文件打开失败!\n");
        return -1;
    }

    char s[256] = "asdkgbweidhow\neniowebfifbibbefb"; // \n可以把字符串截断
    
    fputs(s, f);
    printf("%s\n", s);
    fclose(f);
#endif

#if 0
    FILE *f = fopen("./test1.txt", "r");
    if(f == NULL)
    {
        printf("文件打开失败!\n");
        return -1;
    }

    // char s[256] = {0};
    // 移动光标位置（SEEK_SET  SEEK_CUR  SEEK_END）
    fseek(f, 0, SEEK_END); // 把光标移到末尾
    long fileSize = ftell(f); // 返回当前光标到初始位置的偏移量
    fseek(f, 0, SEEK_SET); // 把光标移到开头

    char *s = (char *)malloc(fileSize);
    fread(s, fileSize, 1, f);
    // 返回当前光标到初始位置的偏移量
    printf("%s\n", s);
    // ptr ：文件内容读取到内存中的地址
    // size ：一次读取的大小
    // n ：读取的次数
    // fread(s, 256, 10, f);

    fclose(f);
#endif

#if 1
    FILE *f = fopen("./test1.txt", "r");
    if(f == NULL)
    {
        printf("文件打开失败!\n");
        return -1;
    }

    // char s[256] = {0};
    // 移动光标位置（SEEK_SET  SEEK_CUR  SEEK_END）
    fseek(f, 0, SEEK_END); // 把光标移到末尾
    long fileSize = ftell(f); // 返回当前光标到初始位置的偏移量
    fseek(f, 0, SEEK_SET); // 把光标移到开头

    char *s = (char *)malloc(fileSize);
    fread(s, fileSize, 1, f);

    FILE *fw = fopen("./test.txt", "w");

    // 回到文件的开头
    rewind(f); // 相当于fseek(f, 0, SEEK_SET)；
    fwrite(s, fileSize, 1, fw);
    // 返回当前光标到初始位置的偏移量
    printf("%s\n", s);
    // ptr ：文件内容读取到内存中的地址
    // size ：一次读取的大小
    // n ：读取的次数
    // fread(s, 256, 10, f);

    fclose(f);
#endif

    return 0;
}